# -*- coding:utf-8 -*-

from py_stealth import *

import datetime

# 资源箱的ID
RESOURCE_BOX_ID = 0x400E4ADC

# 挖矿书的ID，建议16本
WORKRUNEBOOKS = (0x413E3102, 0x413E2E04, 0x413E2FBF, 0x413E2F98,
                 0x413E3853, 0x413E2F16, 0x413E2D1A, 0x413E37DD,
                 0x413E3035, 0x413E3921, 0x413E2FDB, 0x413E3164,
                 0x413E3125, 0x413E2CA0, 0x413E3A8D, 0x413E2F56)
# 卸货符石书的ID
HOMERUNEBOOK = 0x4142C7FE
# 回家的点在书的第几个
HOMERUNEINDEX = 1
# 卸货点的X座标
HOMEX = 2077
# 卸货点的Y座标
HOMEY = 1293
"""
以下内容不要修改
"""
IRON_TYPE = 0x1BF2
TOOLKIT_TYPE = 0x1EBC
SHOVEL_TYPE = 0x0F39
PICK_AXE_TYPE = 0x0E86
RESOURCE = (0x19B7, 0x19BA, 0x19B8, 0x19B9, 0x3197, 0x3195, 0x5732, 0x3192, 0x0F28, 0x3198, 0x3193, 0x3194)

WAITTIME = 1000
LAGWAIT = 10000
RECALLTIME = 3000

TINKERING_BUTTON = 24
SHOVEL_BUTTON = 73

CurrentBook = 0
CurrentRuneIndex = 0


class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y


def check_box():
    FindType(-1, Ground())
    items = GetFindedList()
    if RESOURCE_BOX_ID not in items:
        AddToSystemJournal('没有找到箱子')
        exit(0)

    UseObject(RESOURCE_BOX_ID)
    CheckLag(LAGWAIT)
    Wait(WAITTIME)

    FindType(IRON_TYPE, RESOURCE_BOX_ID)
    if FindFullQuantity() < 200:
        AddToSystemJournal('箱子里面的铁块最少要200个')
        exit(0)

    FindType(TOOLKIT_TYPE, RESOURCE_BOX_ID)
    if FindCount() < 2:
        AddToSystemJournal('箱子里面的钳工工具最少要放2个')
        exit(0)


def remove_item(item_type):
    while FindType(item_type, Backpack()) > 0:
        resource = FindItem()
        MoveItem(resource, GetQuantity(resource), RESOURCE_BOX_ID, 0, 0, 0)
        CheckLag(LAGWAIT)
        Wait(WAITTIME)


def load_material():
    FindTypeEx(IRON_TYPE, 0x0000, RESOURCE_BOX_ID, False)
    iron = FindItem()
    request_quantity = GetQuantity(iron)
    AddToJournal('resource iron count:'+str(request_quantity))
    if request_quantity > 200:
        request_quantity = 200
    MoveItem(iron, request_quantity, Backpack(), 0, 0, 0)
    CheckLag(LAGWAIT)
    Wait(WAITTIME)

    FindType(TOOLKIT_TYPE, RESOURCE_BOX_ID)
    Grab(FindItem(), 1)
    CheckLag(LAGWAIT)
    Wait(WAITTIME)
    toolkit_count = FindCount()
    AddToJournal('resource toolkit count:'+str(toolkit_count))
    if toolkit_count < 3:
        for i in range(3 - toolkit_count):
            make_item(15, TINKERING_BUTTON)


def unload_material():
    remove_item(IRON_TYPE)
    remove_item(TOOLKIT_TYPE)


def hit_button(button_value):
    CheckLag(LAGWAIT)
    Wait(WAITTIME)
    NumGumpButton(GetGumpsCount()-1, button_value)


def make_item(plane_btn, item_btn):
    close_dialog()
    FindType(TOOLKIT_TYPE, Backpack())
    UseObject(FindItem())
    hit_button(plane_btn)
    hit_button(item_btn)
    hit_button(1)


def drop_item(item_type):
    while FindType(item_type, Backpack()) > 0:
        resource = FindItem()
        MoveItem(resource, GetQuantity(resource), RESOURCE_BOX_ID, 0, 0, 0)
        CheckLag(LAGWAIT)
        Wait(WAITTIME)


def close_dialog():
    while GetGumpsCount() > 0:
        CloseSimpleGump(0)


def check_toolkit():
    load_material()
    FindType(SHOVEL_TYPE, Backpack())
    shovel_count = FindCount()
    AddToJournal('resource shovel count:'+str(shovel_count))
    if shovel_count < 3:
        for i in range(3 - shovel_count):
            make_item(15, SHOVEL_BUTTON)
            Wait(2000)
    unload_material()


def recall_rune(rune_book, index):
    while GetGumpsCount() > 0:
        CloseSimpleGump(0)
    result = True
    x = GetX(Self())
    y = GetY(Self())
    CheckLag(LAGWAIT)
    Wait(WAITTIME)
    UseObject(rune_book)
    CheckLag(LAGWAIT)
    if IsGump():
        rune_book_shift = 7
        if NumGumpButton(GetGumpsCount()-1, rune_book_shift + (6*index)):
            CheckLag(LAGWAIT)
            Wait(RECALLTIME)
            result = (x != GetX(Self())) or (y != GetY(Self()))
        else:
            result = False
    else:
        result = False
    return result


def next_rune():
    global CurrentBook, CurrentRuneIndex, WORKRUNEBOOKS
    if CurrentRuneIndex > 15:
        CurrentBook += 1
        CurrentRuneIndex = 0
    if CurrentBook >= len(WORKRUNEBOOKS):
        CurrentBook = 0
        CurrentRuneIndex = 0
    AddToJournal('point: [ '+str(CurrentBook+1)+' - '+str(CurrentRuneIndex+1)+']')
    recall_rune(WORKRUNEBOOKS[CurrentBook], CurrentRuneIndex)
    CurrentRuneIndex += 1
    Wait(WAITTIME)


def reset_status():
    close_dialog()
    back_home()
    check_box()
    check_toolkit()


def generate_points():
    points = []
    x = GetX(Self())
    y = GetY(Self())
    for i in range(-1, 2):
        for j in range(-1, 2):
            points.append(Point(x + i, y + j))
    return points


def get_tiles():
    result = []
    for point in generate_points():
        tiles = ReadStaticsXY(point.x, point.y, WorldNum())
        if tiles:
            tile = tiles.pop()
            result.append(tile)
    return result


def mine(tiles):
    for tile in tiles:
        while True:
            if MaxWeight() < Weight() + 60\
                    or FindType(SHOVEL_TYPE, Backpack()) == 0:
                unload()
                AddToJournal('point: [ '+str(CurrentBook+1)+' - '+str(CurrentRuneIndex+1)+']')
                recall_rune(WORKRUNEBOOKS[CurrentBook], CurrentRuneIndex-1)
            """
            
            mine_tool = 0
            if FindType(PICK_AXE_TYPE, Backpack()) > 0 and ObjAtLayer(LhandLayer()) == 0:
                mine_tool = FindItem()
                Equip(LhandLayer(), mine_tool)
                Wait(1000)
            if TargetPresent():
                CancelTarget()
            CheckLag(LAGWAIT)
            Wait(WAITTIME)
            if mine_tool == 0:
                FindType(SHOVEL_TYPE, Backpack())
                mine_tool = FindItem()
            """
            FindType(SHOVEL_TYPE, Backpack())
            UseObject(FindItem())
            CheckLag(LAGWAIT)
            WaitForTarget(LAGWAIT)
            #AddToJournal('mine to tile tile->'+str(tile.Tile)+' x->'+str(tile.X)+' y->'+str(tile.Y))
            startTime = datetime.datetime.now()
            TargetToTile(tile.Tile, tile.X, tile.Y, tile.Z)
            CheckLag(LAGWAIT)
            journalStr = 'in your backpack|' \
                         'but fail to find any useable ore'
            if not WaitJournalLine(startTime, journalStr, 3000):
                #AddToJournal('mine to x->'+str(tile.X)+' y->'+str(tile.Y)+' fail')
                break


def back_home():
    while HOMEX != GetX(Self()) and HOMEY != GetY(Self()):
        recall_rune(HOMERUNEBOOK, HOMERUNEINDEX-1)
        Wait(WAITTIME)


def unload():
    back_home()
    UseObject(RESOURCE_BOX_ID)
    CheckLag(LAGWAIT)
    Wait(WAITTIME)
    for resource_type in RESOURCE:
        while FindType(resource_type, Backpack()) > 0:
            resource_item = FindItem()
            MoveItem(resource_item, GetQuantity(resource_item), RESOURCE_BOX_ID, 0, 0, 0)
            CheckLag(LAGWAIT)
            Wait(WAITTIME)
    check_toolkit()


def main():
    reset_status()
    while Connected():
        next_rune()
        mine(get_tiles())


main()
